'''
Created on 2016年3月13日

@author: 张志波
'''
import RPi.GPIO as GPIO
import time

#延时
delaytime=0.000001

#初始化引脚信息
RS=17 #显示屏指令线
RW=27
EN=22
P=[18,23,24,25,12,16,20,21] #显示屏数据线

#引脚模式设置
#参数i为引脚编号,m为输入或输出模式
def Pin(i,m):
	if m==0:
		GPIO.setup(i,GPIO.IN)
	elif m==1:
		GPIO.setup(i,GPIO.OUT)

#电平设置
#参数i为引脚编号,m为引脚电平高低
def Level(i,m):
	if m==0:
		GPIO.output(i,GPIO.LOW)
	elif m==1:
		GPIO.output(i,GPIO.HIGH)

#检测电平
#参数i为引脚编号
def ChkLevel(i):
	return GPIO.input(i)

#转2进制
#参数i为要转换的数字
def ToT(i):
	arr = [0]*8
	for a in range(0,8):
		arr[a]=int(i%2)
		i=i/2
	return arr

#写命令
#参数i为要写入的命令
def WriteCmd(i):
	#检测忙
	ChkBusy()
	Level(RS,0)
	Level(RW,0)
	Level(EN,1)
	time.sleep(delaytime)
	#写入
	BusWrite(i)
	Level(EN,0)
	time.sleep(delaytime)

#写字符数据
#参数i为要写入的数据
def WriteData(i):
	#检测忙
	ChkBusy()
	Level(RS,1)
	Level(RW,0)
	Level(EN,1)
	time.sleep(delaytime)
	#写入
	BusWrite(i)
	Level(EN,0)
	time.sleep(delaytime)

#数据总线写入
#参数i为要写入总线的数据
def BusWrite(i):
	#将要写入的数据转为2进制
	arr = ToT(i)
	m=0
	for n in P:
		Level(n,arr[m])
		m+=1

#检查忙
def ChkBusy():
	Level(RS,0)
	Level(RW,1)
	Level(EN,1)
	#写入检测忙指令
	BusWrite(0xff)
	Pin(EN,0)
	while (1):
		#检测输入电平
		if ChkLevel(EN)==1:
			break
		else:
			time.sleep(0.001)
	Pin(EN,1)
	Level(EN,0)

#初始化引脚状态
#参数0为字符模式,1为绘图模式
def Init(i):
	GPIO.setmode(GPIO.BCM)
	Pin(RS,1)
	Pin(RW,1)
	Pin(EN,1)
	for m in P:
		Pin(m,1)
	#选择8位数据流
	#设置字符模式
	if i==0:
		#选择8位数总线,基本指令集
		WriteCmd(0x30)
		time.sleep(delaytime)
		#清屏
		WriteCmd(0x01)
		time.sleep(delaytime)
		#设置游标
		WriteCmd(0x0c)
		time.sleep(delaytime)
	#设置绘图模式 开发中
	elif i==1:
		#清屏
		Init(0)
		#选择8位数总线,扩展指令集
		WriteCmd(0x34)

#发送字符串
def SendWord(i,m=0x80):
	#检测字符串长度
	count=len(i)
	if count>0:
		#初始化
		Init(0)
		#初始地址
		WriteCmd(m)
		for a in range(0,count):
			#获取单个字符的ASCII码
			asi=ord(i[a:a+1])
			#写入字符
			WriteData(asi)

#绘图清屏
def DrawClear():
	Init(1)
	#关闭绘图显示
	WriteCmd(0x34)
	for a in range(0,32):
		WriteCmd(0x80+a)
		WriteCmd(0x80)
		for b in range(0,32):
			WriteData(0x00)
	#开启绘图显示
	WriteCmd(0x36)
	
#图形信息转List
def CodeToList(i):
	#建立数组,用于保存绘图信息
	list = [[['0']*16 for m in range(0,64)]]
	#计数器 记录截取到第几位
	count=int(0)
	#截取字符串 并保存到list中
	for b in range(0,64):
		for a in range(0,16):
				list[0][b][a]=i[count:count+8]
				count=count+8
	return list

#发送绘图信息	
def SendDraw(i):
	DrawClear()
	list=CodeToList(i)
	for a in range(0,2):
		for b in range(0,32):
			WriteCmd(0x80+b)
			#记录写入数组中第几位
			bitcount=0
			#判断上下屏
			if a==0:
				WriteCmd(0x80)
			else:
				WriteCmd(0x80+8)
			for c in range(0,16):
				if a==0:
					str=int(list[0][b][c],2)
				else:
					str=int(list[0][b+32][c],2)
				WriteData(str)
				#WriteData(0xff)
				time.sleep(delaytime)
